home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1995 October / EnigmA AMIGA RUN 01 (1995)(G.R. Edizioni)(IT)[!][issue 1995-10][Aminet 7].iso / Aminet / misc / emu / prlink_080b.lha / prlink-0.8.0b / src / prserver.asm < prev    next >
Assembly Source File  |  1995-06-03  |  23KB  |  1,221 lines

  1.   .processor 6502
  2.   .include "options.inc"
  3.  
  4. #if target & c128
  5. host    = 128
  6. #endif
  7. #if target & c64
  8. host    = 64
  9. #endif
  10. #if target & vic20
  11. host    = 20
  12. #endif
  13. #if target & (pet3001 | pet4001)
  14. host    = 201    ; want 2001 but it must fit in a byte
  15. #endif
  16.  
  17. #if target & (c128 | c64)
  18. #if ramexp & piaexp
  19. pia    = $d7f0 ; the PIA base address.  See also the definition "bank".
  20. #endif
  21. #if ramexp & reuexp
  22. reu    = $df00 ; the REU base address.  See also the definition "bank".
  23. reubmin = $10    ; smallest bank number that refers to the REU banks
  24. #endif
  25. #endif        ; target & (c128 | c64)
  26.  
  27. ; The machines with a VIA that use a VIA control line for handshaking
  28. ; must reset the interrupt flag before it can be used again.
  29.  
  30. clearviaifr = target & (vic20 | pet3001 | pet4001)
  31.  
  32. ; The following constant tells if the cable uses the PA2 handshaking line
  33.  
  34. pa2_used = cable & (pc64 | prlink | prlink88)
  35.  
  36.   seg MAIN
  37.   .org prsrv
  38.  
  39. #if target & (vic20 | c64 | c128)
  40. strval    = $10    ; strobe bit value on the Vic-20/C64/C128
  41.  
  42. start    = $ac    ; some memory locations
  43. end    = $ae
  44. cinv    = $314
  45. #endif        ; target & (vic20 | c64 | c128)
  46.  
  47. #if cable & (pc64 | c64net | transnib)
  48. #if target & (pet3001 | pet4001)
  49. stemp    = $bd    ; memory place that holds the byte that will be received
  50. #else
  51. stemp    = $a7    ; memory place that holds the byte that will be received
  52. #endif
  53. #endif
  54.  
  55. #if target & c128
  56. bstart    = $2d    ; start of basic program text
  57. bend    = $1210 ; end of basic program text
  58.  
  59. bank    = $a9    ; temporary variable that holds the memory bank
  60. stack    = $105    ; offset to the stack while in interrupt
  61.  
  62. peek    = $2a2
  63. peekptr = $2aa
  64. poke    = $2af
  65. pokeptr = $2b9
  66.  
  67. linkprg = $4f4f
  68. basrun    = $5aa6
  69.  
  70. ackval    = 4
  71. ack    = $dd00
  72. data    = $dd01
  73. ddr    = $dd03
  74. strobe    = $dd0d
  75. #endif        ; target & c128
  76.  
  77. #if target & c64
  78. bstart    = $2b    ; start of basic program text
  79. bend    = $2d    ; end of basic program text
  80. #if ramexp
  81. bank    = $a9    ; temporary variable that holds the memory bank
  82. #else
  83. bank    = none    ; non-banked systems
  84. #endif
  85. blnsw    = $cc
  86. crsw    = $d0
  87.  
  88. stack    = $104    ; offset to the stack while in interrupt
  89.  
  90. clr    = $a659
  91. linkprg = $a533
  92. stxpt    = $a68e
  93. newstt    = $a7ae
  94.  
  95. ackval    = 4
  96. ack    = $dd00
  97. data    = $dd01
  98. ddr    = $dd03
  99. strobe    = $dd0d
  100. #endif        ; target & c64
  101.  
  102. #if target & vic20
  103. bstart    = $2b    ; start of basic program text
  104. bend    = $2d    ; end of basic program text
  105. bank    = none
  106. blnsw    = $cc
  107. crsw    = $d0
  108.  
  109. stack    = $104    ; offset to the stack while in interrupt
  110.  
  111. clr    = $c659
  112. linkprg = $c533
  113. stxpt    = $c68e
  114. newstt    = $c7ae
  115.  
  116. ackval    = $20
  117. ack    = $911c
  118. data    = $9110
  119. ddr    = $9112
  120. strobe    = $911d
  121. #endif        ; target & vic20
  122.  
  123. #if target & (pet3001 | pet4001)
  124. start    = $c7    ;; the PET series
  125. end    = $c9
  126. cinv    = $0090
  127.  
  128. bstart    = $28    ; start of basic program text
  129. bend    = $2a    ; end of basic program text
  130. blnsw    = $a7
  131. crsw    = $ac
  132.  
  133. #if ramexp & pet96
  134. bank  = $bf    ; temporary variable that holds the memory bank
  135. latch = $fff0    ; write-only register
  136. #else
  137. bank    = none    ; non-banked systems
  138. #endif
  139.  
  140. stack = $104    ; offset to the stack while in interrupt
  141.  
  142. ackval    = $20    ; CB2 value bit when set to manual control
  143. ack    = $e84c ; VIA CRB
  144. data    = $e84f ; VIA PA without handshake
  145. ddr    = $e843 ; VIA DDRA
  146. strval    = $02    ; VIA CA1 bit in IFR
  147. strobe    = $e84d ; VIA IFR
  148. #endif        ; target & (pet3001 | pet4001)
  149.  
  150. #if target & pet4001    ; for BASIC 4.0
  151. clr    = $b5e9
  152. linkprg = $b4b6
  153. stxpt    = $b622
  154. newstt    = $b74a
  155. #endif
  156. #if target & pet3001    ; for BASIC 2.0
  157. clr    = $c572
  158. linkprg = $c442
  159. stxpt    = $c5a7
  160. newstt    = $c6c4
  161. #endif
  162.  
  163. cmdinfo = 0    ; code for requesting machine type info
  164. cmdload = 1    ; code for loading
  165. cmdsave = 2    ; code for saving
  166. cmdjump = 3    ; code for jumping to an address
  167. cmdrun    = 4    ; code for running a BASIC program
  168.  
  169. mystart:    ; A jump table for external programs
  170.   jmp install        ; Installs the prserver wedge.
  171.   jmp deinstall     ; Removes the prserver wedge.
  172.   jmp send_switch    ; Switches to send configuration, and sends a byte.
  173.   jmp send        ; Sends a byte assuming send configuration.
  174.   jmp receive_switch    ; Switches to receive configuration, and receives a byte.
  175.   jmp receive        ; Receives a byte assuming receive configuration.
  176.   jsr install        ; Reinstalls the prserver wedge and
  177. #if target & c128    ; continues with the previous program.
  178.   jmp $ff33
  179. #else
  180.   pla
  181.   tay
  182.   pla
  183.   tax
  184.   pla
  185.   rti
  186. #endif        ; target & c128
  187.  
  188. install:
  189.   sei
  190.   lda cinv    ; check the original IRQ vector
  191.   ldx cinv+1
  192.   cmp #<irq
  193.   bne irqinit
  194.   cpx #>irq
  195.   beq skipirq
  196. irqinit:    ; if it was different from our irq wedge, install the wedge
  197.   sta oldirq    ; first save the old IRQ vector
  198.   stx oldirq+1
  199.   lda #<irq    ; and then install ours
  200.   sta cinv
  201.   lda #>irq
  202.   sta cinv+1
  203. skipirq:
  204. #if ramexp & piaexp
  205. #if target & c128
  206.   lda #$3e
  207.   sta $ff00
  208. #endif
  209.   ldx #11    ; initialize the PIA
  210. 0$:
  211.   lda piatable-1,x
  212.   sta pia,x
  213.   dex
  214.   bne 0$
  215. #endif        ; ramexp & piaexp
  216. #if cable & (prlink | prlink88 | pc64)
  217. #if target & vic20
  218.   lda #$ef
  219.   and ack
  220.   sta ack    ; set CB1 to trigger on falling edge
  221. #endif
  222. #if target & (pet3001 | pet4001)
  223.   lda ack
  224.   and #%11111110; set CA1 to trigger on falling edge
  225.   ora #%11100000; set CB2 to output with manual control
  226.   sta ack
  227. #endif
  228. #endif        ; cable & (prlink | prlink88 | pc64)
  229. #if cable & transnib
  230.   lda #$40    ; prepare for input: only DRCV is output
  231.   sta data    ; idle state of lines is high
  232.   sta ddr
  233. #endif
  234.   cli
  235.   rts
  236.  
  237. #if ramexp & piaexp
  238. piatable:
  239.   .byte $34,$fe,4,$ff,0,$ff,0,$dc,4,$fe,4
  240. #endif
  241.  
  242. irq:
  243. #if (target & c64) && pa2_used
  244.   lda #ackval    ; this is needed for Action Replay, whose fastload command
  245.   ora ack    ; resets the PA2 line
  246.   sta ack
  247. #endif
  248. #if cable & (prlink | prlink88)
  249.   lda #strval
  250.   bit strobe    ; check the -FLAG signal
  251.   beq return    ; jump if the client didn't want to send anything
  252.   ldx #0
  253.   stx ddr    ; restore the data lines to inputs
  254. #endif
  255. #if cable & pc64
  256.   lda #strval
  257.   bit strobe    ; check the -FLAG signal
  258.   beq return    ; jump if the client didn't want to send anything
  259.   ldx #$f
  260.   stx ddr    ; restore the data lines to inputs/outputs
  261. #endif
  262.  
  263. #if cable & c64net
  264.   lda data
  265.   and #$F8    ; check if the remote host wants to send a byte
  266.   eor #8
  267.   bne return    ; jump if not
  268.  
  269.   lda #$7
  270.   sta data
  271.   sta ddr
  272. #endif
  273.  
  274. #if cable & transnib
  275.   bit data    ; test if DRDY is low.
  276.   bmi return
  277.   lda #$40    ; prepare for input: only DRCV is output
  278.   sta data    ; idle state of lines is high
  279.   sta ddr
  280. #endif
  281.  
  282.   jsr rereceive ; receive byte without requiring handshaking
  283.   cmp #cmdinfo
  284.   bne load    ; branch if the client did not request for host info
  285.   lda #host    ; return the host info byte
  286.   jsr send_switch
  287.   lda #<mystart ; tell the driver start address
  288.   jsr send
  289.   lda #>mystart
  290.   jsr send
  291.   lda bstart    ; and the BASIC start address
  292.   jsr send
  293.   lda bstart+1
  294.   jsr send
  295.  
  296. return:
  297. oldirq = * + 1
  298.   jmp *     ; continue the normal irq (selfmodifying code)
  299.  
  300. load:
  301.   cmp #cmdload    ; was it the command for loading?
  302.   beq 0$
  303.   jmp jump    ; no, skip
  304.  
  305. 0$:
  306.   jsr gethdr    ; get the addresses
  307. #if bank
  308.   lda bank    ; other bank than the default specified => can't be basic
  309.   bne 1$
  310. #endif
  311.   lda start    ; check if it is a basic program
  312.   eor bstart
  313.   bne 1$
  314.   lda start+1
  315.   eor bstart+1
  316. 1$:
  317.   pha        ; accu is 0 if it is a basic program
  318. #if target & (c64 | c128)
  319.   lda $d011
  320.   pha
  321.   lda $d030
  322.   pha
  323.   lda #$1
  324.   sta $d011    ; blank the screen
  325.   sta $d030    ; switch to 2 MHz mode
  326. #endif
  327.  
  328. #if ramexp & reuexp
  329.   lda bank
  330.   cmp #reubmin    ; is it a REU bank?
  331.   bcc noreu$    ; no, do not save REC registers on stack
  332.  
  333. #if actionreuplay
  334.   lda #$2a
  335.   sta $de00    ; enable Action Replay RAM at $df00 (disable the ROM)
  336.         ; Action Replay has one write-only I/O register at $de00-$deff.
  337.         ; Its bits are as follows:
  338.         ; 7 - not used
  339.         ; 6 - probably resets the IRQ/NMI flipflop in the freezer mode
  340.         ; 5 - enables RAM at I/O2
  341.         ; 4 - bank selector
  342.         ; 3 - bank selector
  343.         ; 2 - 1=cartridge off
  344.         ; 1 - 1=-EXROM high
  345.         ; 0 - 1=-GAME low
  346. #else
  347.   ldx #10
  348. 11$:
  349.   lda reu,x
  350.   pha
  351.   dex
  352.   bne 11$
  353. #endif
  354.   lda end+1    ; store the end of file pointer high byte
  355.   pha
  356.   jsr reuinit    ; initialize the REU registers.  C flag is set at this stage.
  357. 12$:
  358.   jsr receive
  359.   sta (start),y
  360.   jsr incmptreu
  361.   bne 12$
  362.  
  363.   dec $d030    ; switch to 1 MHz mode
  364.   lda #$f2
  365.   sta reu+1    ; swap the REU memory back
  366.   pla
  367.   sta start+1    ; adjust the end address pointers
  368.   sta end+1
  369.  
  370. #if actionreuplay
  371.   lda #$0a
  372.   sta $de00    ; restore normal Action Replay configuration
  373. #else        ; actionreuplay
  374.   ldx #0
  375. 13$:
  376.   inx
  377.   pla
  378.   sta reu,x
  379.   cpx #10
  380.   bne 13$
  381. #endif        ; actionreuplay
  382.   jmp endload
  383.  
  384. noreu$:
  385. #endif        ; ramexp & reuexp
  386.  
  387. #if ramexp & piaexp
  388.   lda end+1    ; store the end of file pointer high byte
  389.   pha
  390.   lda pia    ; store the PIA memory configuration
  391.   pha
  392. #if target & c128
  393.   lda $d506    ; store the common memory configuration
  394.   pha
  395. #endif
  396.   jsr piainit    ; initialize the PIA expansion (with $d506 value in A)
  397. 2$:
  398.   jsr receive
  399.   sta (start),y
  400.   jsr incmptr
  401.   bne 2$
  402.  
  403. #if target & c128
  404.   pla        ; restore the original MMU banking
  405.   ldx #0    ; enable all ROMs, select RAM bank 0
  406.   stx $d500
  407.   sta $d506    ; restore the common memory configuration
  408. #endif
  409.   pla
  410.   sta pia
  411.   pla
  412.   sta start+1    ; adjust the end address pointers
  413.   sta end+1
  414. #else        ; ramexp & piaexp
  415. #if target & c128
  416.   lda pokeptr
  417.   pha
  418.   lda #start
  419.   sta pokeptr
  420.  
  421. 2$:
  422.   jsr receive    ; get the bytes
  423.   ldx bank
  424.   jsr poke
  425.   jsr incmptr    ; update the pointer
  426.   bne 2$
  427.  
  428.   sty bank
  429.   pla
  430.   sta pokeptr
  431. #else        ; target & c128
  432. 2$:
  433.   jsr receive    ; get the bytes
  434.   sta (start),y
  435.   jsr incmptr    ; update the pointer
  436.   bne 2$
  437. #endif        ; target & c128
  438. #endif        ; ramexp & piaexp
  439.  
  440. endload:
  441. #if target & (c64 | c128)
  442.   pla
  443.   sta $d030    ; restore original speed
  444.   pla
  445.   sta $d011    ; and screen mode
  446. #endif
  447.  
  448.   pla
  449.   bne 0$    ; it was not a basic program
  450.   lda end    ; set the basic end address
  451.   sta bend
  452.   lda end+1
  453.   sta bend+1
  454.   jsr linkprg    ; relink the program
  455. #if target & c128
  456.   lda #0
  457.   sta $ff00    ; restore the MMU configuration (linkprg changes it)
  458. #endif
  459. 0$:
  460.   jmp (oldirq)
  461.  
  462. jump:
  463.   cmp #cmdjump    ; was it the command for jumping?
  464.   bne save    ; no, skip
  465.  
  466.   jsr receive    ; get the memory configuration (for the c128)
  467. #if target & c128
  468.   sta bank    ; and temporarily store it
  469. #endif
  470.   jsr receive    ; get the jump address low
  471.   tax
  472.   jsr receive    ; get the jump address high
  473.   pha        ; and store it
  474.   txa
  475.   pha        ; store the jump address low
  476.   lda #0
  477.   pha        ; clear the flags
  478.   pha        ; and the registers
  479.   pha
  480.   pha
  481. #if target & c128
  482.   lda bank
  483.   pha        ; store the MMU configuration
  484. #endif
  485.   jsr deinstall ; deinstall the IRQ routine
  486. #if target & c128
  487. #else
  488.   sta crsw    ; turn the cursor off
  489.   sta blnsw
  490. #endif
  491.   jmp (oldirq)
  492.  
  493. save:
  494.   cmp #cmdsave
  495.   bne run
  496.  
  497. #if target & (c64 | c128)
  498.   lda $d011
  499.   pha
  500.   lda $d030
  501.   pha
  502.   lda #$1
  503.   sta $d011    ; blank the screen
  504.   sta $d030    ; switch to 2 MHz mode
  505. #endif
  506.  
  507.   jsr gethdr    ; get the pointers
  508.  
  509. #if ramexp & reuexp
  510.   lda bank
  511.   cmp #reubmin    ; is it a REU bank?
  512.   bcc noreu$    ; no, jump to normal save
  513.  
  514. #if actionreuplay
  515.   lda #$2a
  516.   sta $de00    ; disable Action ROM at $df00
  517. #else
  518.   ldx #10
  519. 11$:
  520.   lda reu,x    ; store the REU registers
  521.   pha
  522.   dex
  523.   bne 11$
  524. #endif
  525.   lda end+1    ; store the end of file pointer high byte
  526.   pha
  527.   jsr reuinit    ; initialize the REU registers.  C flag is set at this stage.
  528. #if send != send_switch
  529.   lda (start),y    ; unrolled once
  530.   jsr send_switch
  531.   jsr incmptreu
  532.   beq skiploop$
  533. #endif        ; send != send_switch
  534. loop$:
  535.   lda (start),y
  536.   jsr send
  537.   jsr incmptreu
  538.   bne loop$
  539. skiploop$:
  540.  
  541.   dec $d030    ; switch to 1 MHz mode
  542.   lda #$f2
  543.   sta reu+1    ; swap the REU memory back
  544.   pla
  545.   sta start+1
  546.   sta end+1
  547.  
  548. #if actionreuplay
  549.   lda #$0a
  550.   sta $de00    ; restore normal Action Replay configuration
  551. #else        ; actionreuplay
  552.   ldx #0
  553. 13$:
  554.   inx
  555.   pla
  556.   sta reu,x
  557.   cpx #10
  558.   bne 13$
  559. #endif        ; actionreuplay
  560.   jmp endsave
  561.  
  562. noreu$:
  563. #endif        ; ramexp & reuexp
  564.  
  565. #if ramexp & piaexp
  566.   lda pia    ; store the PIA memory configuration
  567.   pha
  568. #if target & c128
  569.   lda $d506    ; store the common memory configuration
  570.   pha
  571. #endif
  572.   jsr piainit    ; initialize the PIA expansion (with $d506 value in A)
  573. #if send != send_switch
  574.   lda (start),y    ; unrolled once
  575.   jsr send_switch
  576.   jsr incmptr
  577.   beq skiploop$
  578. #endif        ; send != send_switch
  579. loop$:
  580.   lda (start),y
  581.   jsr send
  582.   jsr incmptr
  583.   bne loop$
  584. skiploop$:
  585.  
  586. #if target & c128
  587.   pla
  588.   ldx #0
  589.   stx $d500
  590.   sta $d506
  591. #endif
  592.   pla
  593.   sta pia
  594. #else        ; ramexp & piaexp
  595. #if target & c128
  596.   lda peekptr
  597.   pha
  598.   lda #start
  599.   sta peekptr
  600.  
  601. #if send != send_switch
  602.   ldx bank    ; unrolled once
  603.   jsr peek
  604.   jsr send_switch
  605.   jsr incmptr
  606.   beq skiploop$
  607. #endif        ; send != send_switch
  608.  
  609. loop$:
  610.   ldx bank
  611.   jsr peek
  612.   jsr send
  613.   jsr incmptr
  614.   bne loop$
  615. skiploop$:
  616.  
  617.   sty bank
  618.   pla
  619.   sta peekptr
  620. #else        ; target & c128
  621. #if target & c64
  622. #if send != send_switch
  623.   ldx 1        ; unrolled once
  624.   lda #$34
  625.   sta 1     ; switch to 64 kB RAM config
  626.   lda (start),y
  627.   stx 1     ; restore the normal config
  628.   jsr send_switch
  629.   jsr incmptr
  630.   beq skiploop$
  631. #endif        ; send != send_switch
  632.  
  633.   ldx 1
  634. loop$:
  635.   lda #$34
  636.   sta 1     ; switch to 64 kB RAM config
  637.   lda (start),y
  638.   stx 1     ; restore the normal config
  639. #else        ; target & c64
  640. #if send != send_switch
  641.   lda (start),y    ; unrolled once
  642.   jsr send_switch
  643.   jsr incmptr
  644.   beq skiploop$
  645. #endif        ; send != send_switch
  646. loop$:
  647.   lda (start),y
  648. #endif        ; target & c64
  649.   jsr send
  650.   jsr incmptr
  651.   bne loop$
  652. skiploop$:
  653. #endif        ; target & c128
  654. #endif        ; ramexp & piaexp
  655.  
  656. endsave:
  657. #if target & (c64 | c128)
  658.   pla
  659.   sta $d030    ; restore original speed
  660.   pla
  661.   sta $d011    ; and screen mode
  662. #endif        ; target & (c64 | c128)
  663.  
  664. return2:
  665.   jmp (oldirq)    ; return from interrupt
  666.  
  667. run:
  668.   cmp #cmdrun
  669.   bne return2
  670.  
  671.   jsr deinstall ; Install the original interrupt routine
  672. #if target & c128
  673.   cli        ; process the pending interrupt in a very kludgeous manner.
  674.   jmp basrun
  675. #else
  676.   sta crsw    ; turn the cursor off
  677.   sta blnsw
  678.   cli        ; process the pending interrupt in a very kludgeous manner.
  679.   jsr clr    ; The stack won't run out, since the BASIC clr call
  680.         ; initializes the stack pointer.
  681.   jsr stxpt    ; Set the BASIC text pointer (to the beginning of the prg)
  682.   jmp newstt    ; BASIC warm start
  683. #endif
  684.  
  685. deinstall:    ; restore the original interrupt routine
  686.   lda oldirq
  687.   sta cinv
  688.   lda oldirq+1
  689.   sta cinv+1
  690.   rts
  691.  
  692. gethdr:
  693.   jsr receive    ; get the memory bank byte
  694. #if ramexp
  695.   sta bank
  696. #else
  697. #if target & c128
  698.   lsr
  699.   ror
  700.   ror
  701.   ora #$3f
  702.   sta bank
  703. #endif        ; target & c128
  704. #endif        ; ramexp
  705.   lda #0    ; send the acknowledgement code 0
  706.   jsr send_switch
  707.   jsr receive_switch ; get the file start and end vectors
  708.   sta start
  709.   jsr receive
  710.   sta start+1
  711.   jsr receive
  712.   sta end
  713.   jsr receive
  714.   sta end+1
  715.   rts
  716.  
  717. #if ramexp & piaexp
  718. incmptr:    ; increment and compare the current byte pointer
  719.   inc start    ; and change the PIA bank if necessary.
  720.   bne 0$
  721.   inc start+1
  722.   bpl 0$
  723.   dex        ; decrease the bank jump counter
  724.   lda #$40
  725.   sta start+1    ; restore the address
  726.   clc
  727.   lda #$10
  728.   adc pia
  729.   sta pia    ; and adjust the PIA bank
  730. 0$:
  731.   txa        ; is it the last bank?
  732.   bne 1$    ; no, return
  733.   lda start    ; perform the comparison
  734.   cmp end
  735.   bne 1$
  736.   lda start+1
  737.   cmp end+1
  738. 1$:
  739.   rts
  740. #else        ; ramexp & piaexp
  741. incmptr:    ; increment and compare the current byte pointer.
  742.   inc start    ; increment.
  743.   bne 0$
  744.   inc start+1
  745. 0$:
  746.   lda start    ; compare.  if start == end, the zero flag will be set.
  747.   cmp end
  748.   bne 1$
  749.   lda start+1
  750.   cmp end+1
  751. 1$:
  752.   rts
  753. #endif        ; ramexp & piaexp
  754.  
  755. #if ramexp & reuexp
  756. incmptreu:
  757.   inc start    ; increment and compare the current byte pointer
  758.   bne 0$    ; and transfer another REU block in if necessary.
  759.   inc start+1
  760.   bpl 0$
  761.   dex        ; decrease the bank jump counter
  762.   dec $d030    ; slow down to 1 MHz
  763.   lda #$f2
  764.   sta reu+1    ; swap the buffers
  765.   lda #$40
  766.   sta start+1    ; restore the REU buffer address
  767.   clc
  768. #if actionreuplay
  769.   adc bank
  770.   sta bank
  771. #else
  772.   adc reu+5
  773. #endif
  774.   sta reu+5    ; update the REU memory pointer
  775.   lda #$f2
  776.   sta reu+1    ; swap the buffers
  777.   inc $d030    ; switch back to 2 MHz mode
  778. 0$:
  779.   txa        ; is it the last bank?
  780.   bne 1$    ; no, return
  781.   lda start    ; perform the comparison
  782.   cmp end
  783.   bne 1$
  784.   lda start+1
  785.   cmp end+1
  786. 1$:
  787.   rts
  788. #endif        ; ramexp & reuexp
  789.  
  790. #if cable & (prlink | prlink88)
  791.  
  792.   ; .A := data, .Y := 00, .X preserved
  793. receive_switch:
  794.         ;;; wait for first part of handshake
  795.   lda #strval
  796. 1$:
  797.   bit strobe    ; wait for handshaking
  798.   beq 1$
  799. #if clearviaifr
  800.   sta strobe
  801. #endif        ; clearviaifr
  802.  
  803.         ;;; and only then switch data direction.
  804.   lda #0    ; switch back to inputs
  805.   sta ddr
  806.  
  807.   beq receive1    ; branch always
  808.  
  809. receive:
  810. #if clearviaifr
  811. rereceive:    ; rereceive (without handshake) is only different for the CIA
  812. #endif
  813.   lda #strval
  814. 0$:
  815.   bit strobe    ; wait for handshaking
  816.   beq 0$
  817. #if clearviaifr
  818.   sta strobe
  819. #else
  820. rereceive:    ; rereceive (receive without handshaking) for the CIA
  821. #endif        ; clearviaifr
  822. receive1:
  823.   lda #ackval
  824.   eor ack
  825.   ldy data    ; read the byte
  826.   sta ack    ; acknowledge
  827.   tya
  828.   ldy #0
  829.   rts
  830.  
  831.   ; .A trashed, .Y := 00, .X preserved
  832. send_switch:
  833.         ;;; wait for first part of handshake
  834.   tay
  835.   lda #strval
  836. 1$:
  837.   bit strobe    ; wait for handshaking
  838.   beq 1$
  839. #if clearviaifr
  840.   sta strobe
  841. #endif
  842.         ;;; and only then switch data direction.
  843. #if cable & prlink88
  844.   lda #$ff
  845. #else
  846.   lda #$0f
  847. #endif
  848.   sta ddr    ; set the data lines to output
  849.   bne send1    ; branch always
  850.  
  851. send:
  852.   tay
  853.   lda #strval
  854. 0$:
  855.   bit strobe    ; wait for handshaking
  856.   beq 0$
  857. #if clearviaifr
  858.   sta strobe
  859. #endif
  860. send1:
  861. #if cable & prlink88
  862. #else
  863.   tya
  864.   sta data    ; send the low nybble
  865.   lsr
  866.   lsr
  867.   lsr
  868.   lsr
  869.   tay        ; move the high nybble to y
  870.   lda #ackval
  871.   eor ack
  872.   sta ack    ; ack: the low nybble is on the bus
  873.   lda #strval
  874. 1$:
  875.   bit strobe    ; handshake
  876.   beq 1$
  877. #if clearviaifr
  878.   sta strobe
  879. #endif        ; via
  880. #endif        ; prlink88
  881.   sty data    ; send the high nybble (or the whole byte, for prlink88)
  882.   ldy #0
  883.   lda ack
  884.   eor #ackval
  885.   sta ack    ; ack: the high nybble is on the bus
  886.   rts
  887.  
  888. #endif        ; prlink | prlink88
  889.  
  890. #if cable & pc64
  891.  
  892.   ; .A := data, .Y := 00, .X preserved
  893. receive_switch:
  894. receive:
  895. #if clearviaifr
  896. rereceive:
  897. #endif
  898.   lda #strval
  899. 0$:
  900.   bit strobe    ; wait for handshaking
  901.   beq 0$
  902. #if clearviaifr
  903.   sta strobe
  904. #else
  905. rereceive:
  906. #endif
  907.   lda ack
  908.   and #255 - ackval
  909.   ldy data
  910.   sta ack
  911.   tya
  912.   lsr
  913.   lsr
  914.   lsr
  915.   lsr
  916.   sta stemp
  917.   lda #strval
  918. 1$:
  919.   bit strobe
  920.   beq 1$
  921. #if clearviaifr
  922.   sta strobe
  923. #endif
  924.   lda ack
  925.   ora #ackval
  926.   tay
  927.   lda data
  928.   sty ack
  929.   and #$F0
  930.   ora stemp
  931.   ldy #0
  932.   rts
  933.  
  934.   ; .A trashed, .Y := 00, .X preserved
  935. send_switch:
  936. send:
  937.   tay
  938.   lda #strval
  939. 0$:
  940.   bit strobe    ; wait for handshaking
  941.   beq 0$
  942. #if clearviaifr
  943.   sta strobe
  944. #endif
  945.   sty data
  946.   lda ack
  947.   and #255 - ackval
  948.   sta ack
  949.   tya
  950.   lsr
  951.   lsr
  952.   lsr
  953.   lsr
  954.   tay
  955.   lda #strval
  956. 1$:
  957.   bit strobe    ; wait for handshaking
  958.   beq 1$
  959. #if clearviaifr
  960.   sta strobe
  961. #endif
  962.   sty data
  963.   lda ack
  964.   ora #ackval
  965.   sta ack
  966.   ldy #0
  967.   rts
  968.  
  969. #endif        ; pc64
  970.  
  971. #if cable & c64net
  972.  
  973.   ; .A := data, .Y := 00, .X preserved
  974. receive_switch:
  975. receive:
  976. rereceive:
  977.   lda #8
  978. 0$:
  979.   bit data    ; initial handshaking
  980.   beq 0$
  981.   lda data    ; get the high nybble
  982.   and #$f0
  983.   sta stemp
  984.   lda #8
  985.   sta data    ; acknowledge (place 0 on PB2)
  986. 1$:
  987.   bit data    ; wait for acknowledgement
  988.   bne 1$
  989.   ldy #4
  990.   lda data    ; get the low nybble
  991.   sty data    ; acknowledge
  992.   ldy #0
  993.   lsr
  994.   lsr
  995.   lsr
  996.   lsr
  997.   ora stemp
  998.   rts
  999.  
  1000.   ; .A trashed, .Y := 00, .X preserved
  1001. send_switch:    ; switch to sending and send
  1002. send:
  1003.   tay
  1004. 0$:
  1005.   lda data    ; initial handshaking
  1006.   and #$f8
  1007.   eor #$f0
  1008.   bne 0$
  1009.   lda #0
  1010.   sta data
  1011. 1$:
  1012.   lda data
  1013.   bne 1$
  1014.   tya
  1015.   ora #4
  1016.   sta data    ; send the lowest bit pair
  1017.   lda #8
  1018. 2$:
  1019.   bit data    ; wait for acknowledgement
  1020.   beq 2$
  1021.   tya
  1022.   lsr
  1023.   lsr
  1024.   tay
  1025.   and #3
  1026.   sta data    ; send the lowest bit pair but one
  1027.   lda #8
  1028. 3$:
  1029.   bit data    ; wait for acknowledgement
  1030.   bne 3$
  1031.   tya
  1032.   lsr
  1033.   lsr
  1034.   tay
  1035.   ora #4
  1036.   sta data    ; send the highest bit pair but one
  1037.   lda #8
  1038. 4$:
  1039.   bit data    ; wait for acknowledgement
  1040.   beq 4$
  1041.   tya
  1042.   lsr
  1043.   lsr
  1044.   sta data    ; send the highest bit pair
  1045.   lda #8
  1046. 5$:
  1047.   bit data    ; wait for acknowledgement
  1048.   bne 5$
  1049.   lda #4
  1050.   sta data
  1051.   ldy #0
  1052.   rts
  1053.  
  1054. #endif        ; pc64
  1055.  
  1056. #if cable & transnib
  1057.  
  1058.   ; .A := data, .Y := 00, .X preserved
  1059. receive_switch:
  1060.   lda #$40    ; $40 is DRCV (output), $80 is DRDY (input)
  1061.   sta ddr
  1062. receive:
  1063. rereceive:
  1064.   jsr recvnyb    ; high nybble first
  1065.   asl
  1066.   asl
  1067.   asl
  1068.   asl
  1069.   sta stemp
  1070.   jsr recvnyb
  1071.   ldy #0    ; (y is preserved in this function)
  1072.   ora stemp
  1073.   rts
  1074.  
  1075. recvnyb:
  1076. rdrdyhi:
  1077.   bit data    ; - Receiver starts waiting for DRDY to go low.
  1078.   bmi rdrdyhi
  1079.         ; - Sender puts nybble on data lines, pulls DRDY low and waits
  1080.         ; for DRCV to go low.
  1081.   lda data    ; - Receiver gets nybble,
  1082.   and #$ff-$40    ;   pulls DRCV low
  1083.   sta data
  1084. rdrdylo:
  1085.   bit data    ;   and waits for DRDY to go high.
  1086.   bpl rdrdylo
  1087.         ; - Sender pulls DRDY high and waits for DRCV to go high.
  1088.   ora #$40
  1089.   sta data    ; - Receiver pulls DRCV high
  1090.   and #$0f
  1091.   rts
  1092.  
  1093.   ; .A trashed, .Y := 00, .X preserved
  1094. send_switch:
  1095.   ldy #$4f    ; $80 is DRCV (input), $40 is DRDY (output)
  1096.   sty ddr    ; note that the names are swapped from receiving but the
  1097.         ; data direction isn't!
  1098. send:
  1099.   tay        ; high nybble first
  1100.   lsr
  1101.   lsr
  1102.   lsr
  1103.   lsr
  1104.   jsr sendnyb
  1105.   tya
  1106.   and #$0f    ; fall through to send low nybble
  1107.   ldy #0    ; clear y
  1108.  
  1109. sendnyb:    ; - Receiver starts waiting for DRDY to go low.
  1110.   sta data    ; - Sender puts nybble on data lines, pulls DRDY low and
  1111. rdrcvhi:
  1112.   bit data    ;   waits or DRCV to go low.
  1113.   bmi rdrcvhi
  1114.         ; - Receiver gets nybble, pulls DRCV low
  1115.         ;   and waits for DRDY to go high.
  1116.   ora #$40    ; - Sender pulls DRDY high and
  1117.   sta data
  1118. rdrcvlo:
  1119.   bit data    ;   waits for DRCV to go high.
  1120.   bpl rdrcvlo
  1121.  
  1122.   rts
  1123.  
  1124. #endif
  1125.  
  1126. #if ramexp & piaexp
  1127. piainit:
  1128. #if target & c128
  1129.   ora #$3f    ; the accu must be loaded with $d506 when calling this routine
  1130.   sta $d506    ; set the MMU configuration to 32kB common memory (top and low)
  1131.   lda bank
  1132.   and #$f
  1133.   lsr
  1134.   ror
  1135.   ror
  1136.   tax
  1137.   and #$c0
  1138.   ora #2
  1139.   sta $d500    ; set the MMU banking (disabling the BASIC ROM)
  1140.   txa
  1141.   ror
  1142.   ror
  1143. #else
  1144.   lda bank
  1145.   asl
  1146.   asl
  1147.   asl
  1148.   asl
  1149. #endif
  1150.   eor #$c0
  1151.   and #$c0
  1152.   ora #$c
  1153.   sta pia    ; store the PIA banking configuration
  1154.   lda start+1
  1155.   lsr
  1156.   lsr
  1157.   and #$30
  1158.   ora pia
  1159.   sta pia    ; set the initial PIA configuration
  1160. #endif        ; ramexp & piaexp
  1161. #if ramexp
  1162. rptrinit:
  1163.   sec
  1164.   lda end+1
  1165.   ora #$3f
  1166.   sbc start+1    ; get the amount of bank crossings
  1167.   asl
  1168.   rol
  1169.   rol
  1170.   and #3
  1171.   tax        ; and store it to x
  1172.   bne 0$    ; check for address wraparound
  1173.   lda start
  1174.   cmp end    ; if start >= end, the amount of bank crossings will be 4.
  1175.   lda start+1
  1176.   sbc end+1
  1177.   bcc 0$
  1178.   ldx #4
  1179. 0$:
  1180.   lda start+1
  1181.   and #$3f
  1182.   ora #$40
  1183.   sta start+1
  1184.   lda end+1
  1185.   and #$3f
  1186.   ora #$40
  1187.   sta end+1
  1188.   rts
  1189. #endif        ; ramexp
  1190.  
  1191. #if ramexp & reuexp
  1192. reuinit:
  1193.   lda #0
  1194.   ldx #$40
  1195.   sta reu+2    ; set the buffer address for the C64/C128
  1196.   stx reu+3
  1197.   sta reu+7    ; set the buffer length
  1198.   stx reu+8
  1199.   sta reu+9    ; reset some other registers
  1200.   sta reu+10
  1201.   lda bank
  1202.   sbc #reubmin    ; set the memory bank (C flag initially set)
  1203.   sta reu+6
  1204.   lda start    ; set the start address in the REU
  1205.   sta reu+4
  1206.   lda start+1
  1207.   sta reu+5
  1208. #if actionreuplay
  1209.   sta bank
  1210. #endif
  1211. #if target & c128
  1212.   lda #2
  1213.   sta $ff00    ; switch to RAM bank 0 and disable the BASIC ROM
  1214. #endif
  1215.   dec $d030    ; slow down to 1 MHz
  1216.   lda #$f2
  1217.   sta reu+1    ; swap the buffers
  1218.   inc $d030    ; speed up again
  1219.   jmp rptrinit
  1220. #endif        ; ramexp & reuexp
  1221.